package mapper

import (
	"bytes"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"go-zero-project/services/user/rpc/internal/mapper/bo"
	"go-zero-project/services/user/rpc/internal/mapper/entity"
	"gorm.io/gorm"
)

const roleSqlColumn = "role_id,role_name,remark,dept_id,create_time"

type RoleMapper struct {
}

func NewRoleMapper() *RoleMapper {
	return &RoleMapper{}
}

func (mapper *RoleMapper) SelectOne(db *gorm.DB, bo bo.SysRoleBO) (entity.SysRoleEntity, error) {
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	whereSql := mapper.getAllWhereSql(bo)
	var user entity.SysRoleEntity
	logx.Infof(whereSql.String())
	tx = tx.Select(roleSqlColumn).Where(whereSql.String()).First(&user)
	return user, tx.Error
}

func (mapper *RoleMapper) SelectCount(db *gorm.DB, bo bo.SysRoleBO) (int64, error) {
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	whereSql := mapper.getAllWhereSql(bo)
	var total int64
	userEntity := entity.SysRoleEntity{}
	tx = tx.Select(roleSqlColumn).Table(userEntity.TableName()).Where(whereSql.String()).Count(&total)
	return total, tx.Error
}

func (mapper *RoleMapper) SelectList(db *gorm.DB, bo bo.SysRoleBO) ([]entity.SysRoleEntity, error) {
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	whereSql := mapper.getAllWhereSql(bo)
	logx.Infof(whereSql.String())
	whereSql.WriteString(" order by create_time desc")
	var retList []entity.SysRoleEntity
	if bo.PageSize > 0 {
		// 查询语句
		tx = tx.Select(roleSqlColumn).Where(whereSql.String()).Offset(bo.StartIndex).Limit(bo.PageSize).Find(&retList)
	} else {
		// 查询语句
		tx = tx.Select(roleSqlColumn).Where(whereSql.String()).Find(&retList)
	}
	return retList, tx.Error
}

func (mapper *RoleMapper) getAllWhereSql(roleBO bo.SysRoleBO) bytes.Buffer {
	var whereSql bytes.Buffer
	whereSql.WriteString(defaultWhere)
	if roleBO.RoleId > 0 {
		whereSql.WriteString(fmt.Sprintf(" and role_id =%d", roleBO.RoleId))
	}
	if roleBO.NeRoleId > 0 {
		whereSql.WriteString(fmt.Sprintf(" and role_id !=%d", roleBO.NeRoleId))
	}
	if len(roleBO.RoleName) > 0 || roleBO.RoleName != "" {
		whereSql.WriteString(fmt.Sprintf(" and role_name ='%s'", roleBO.RoleName))
	}
	if len(roleBO.RoleNameLike) > 0 || roleBO.RoleNameLike != "" {
		whereSql.WriteString(fmt.Sprintf(" role_name  like concat ('%s','%s','%s')",
			"%", roleBO.RoleNameLike, "%"))
	}
	if len(roleBO.Remark) > 0 || roleBO.Remark != "" {
		whereSql.WriteString(fmt.Sprintf(" and remark ='%s'", roleBO.Remark))
	}
	if roleBO.DeptId > 0 {
		whereSql.WriteString(fmt.Sprintf(" and dept_id =%d", roleBO.DeptId))
	}
	if roleBO.StartTime != nil {
		whereSql.WriteString(fmt.Sprintf(" and create_time >='%s'", roleBO.StartTime))
	}
	if roleBO.EndTime != nil {
		whereSql.WriteString(fmt.Sprintf(" and update_tim <'%s'", roleBO.EndTime))
	}
	return whereSql
}

func (mapper *RoleMapper) SelectListByUserId(db *gorm.DB, userId int64) ([]entity.SysRoleEntity, error) {
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	var userRoleArr []entity.SysRoleEntity
	roleEntity := entity.SysUserRoleEntity{}
	tx = tx.Select("t1.role_id,t1.role_name,t1.remark,t1.dept_id,t1.create_time").
		Table(roleEntity.TableName()).Joins("left join sys_role t1 on sys_user_role.role_id=t1.role_id").
		Where("sys_user_role.user_id", userId).Find(&userRoleArr)
	return userRoleArr, tx.Error
}

// QueryAllMenuId 查询用户的所有菜单ID
func (mapper *RoleMapper) QueryAllMenuId(db *gorm.DB, userId int64) ([]int64, error) {
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	var menuIdArr []int64
	tx = tx.Select("distinct rm.menu_id ").Table("sys_user_role as ur").
		Joins("left join sys_role_menu rm on ur.role_id = rm.role_id").
		Where("ur.user_id", userId).Find(&menuIdArr)
	return menuIdArr, tx.Error
}

func (mapper *RoleMapper) DeleteRoleId(db *gorm.DB, roleIdArr []int64) error {
	if len(roleIdArr) < 1 {
		return nil
	}
	tx := db.Where("role_id in ?", roleIdArr).Delete(&entity.SysRoleEntity{})
	return tx.Error

}

func (mapper *RoleMapper) SaveRole(db *gorm.DB, roleEntity entity.SysRoleEntity) (int64, error) {
	tx := db.Create(&roleEntity)
	return roleEntity.RoleId, tx.Error
}

func (mapper *RoleMapper) Update(db *gorm.DB, roleEntity entity.SysRoleEntity) error {
	tx := db.Where("role_id = ?", roleEntity.RoleId).Omit("role_id").
		UpdateColumns(roleEntity)
	return tx.Error
}
